package fun.codedesign.yinxue.code.php2java.rule;

import fun.codedesign.yinxue.code.php2java.rule.statement.ArrayStatementRule;
import fun.codedesign.yinxue.code.php2java.rule.word.*;
import fun.codedesign.yinxue.util.StringUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static fun.codedesign.yinxue.util.StringUtil.toUpperCaseFirstChar;

public class Php2JavaRuleChain {

    public static Php2JavaRuleChain WORD_CHAIN = defaultWordChain();
    public static Php2JavaRuleChain STATMENT_CHAIN = defaultStatementChain();

    public static Php2JavaRuleChain PARAM_CHAIN = defaultParamChain();
    private List<WordRule> rules = new ArrayList<>();

    private static Php2JavaRuleChain defaultWordChain() {
        return chain(ThisWordRule.class, ArrowWordRule.class, DollarWordRule.class, UnderLineWordRule.class,
                SemicolonReturnLineWordLine.class,
                DoubleColonWordRule.class,
                SingleQuataWordRule.class,
                // 关键词
                KeyWordNeedWhitespaceRule.class,
                ForeachWordRule.class,
                AsWordRule.class,
                BraceWordRule.class);
    }

    private static Php2JavaRuleChain defaultStatementChain() {
        return chain(ArrayStatementRule.class);
    }

    private static Php2JavaRuleChain defaultParamChain() {
        return chain(BasicTypeWhiteSpaceWordRule.class);
    }

    public static Php2JavaRuleChain chain(Class<? extends WordRule>... rules) {
        Php2JavaRuleChain php2JavaRuleChain = new Php2JavaRuleChain();
        for (Class<? extends WordRule> rule : rules) {
            try {
                php2JavaRuleChain.rules.add(rule.newInstance());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return php2JavaRuleChain;
    }


    // 替换的符号值
    private Map<String, String> replaceSymbolMap = new HashMap<>();

    // 猜测变量类型
    private Map<String, String> thinkTypeMap = new HashMap<>();

    // 变量需要修改
    public static final String VARIABLE_NEED_CHANGE = "variable_need_change";


    // 类型需要确认
    public static final String TYPE_NEED_CONFIRM = "type_need_confirm";

    // 是构造器方法
    public static final String IS_CONSTRUCTOR = "is_constructor";

    public static final String DEFAULT_OBJECT = "Object";

    public String invokeRules(String text) {
        String target = text;
        for (WordRule rule : rules) {
            if (rule.isMatch(target)) {
                target = rule.invoke(target);
            }
        }
        return target;
    }


    // 类的首字母大写
    public String typeName2UpperCaseFirstChar(String originTypeName) {
        String newTypename = toUpperCaseFirstChar(originTypeName);
        replaceSymbolMap.put(originTypeName, newTypename);
        return newTypename;
    }


    // 导入行将 \ 替换为 .
    public String importLine2dotSeparate(String originImportLine) {
        String newImportLine = originImportLine.replace("\\", ".");
        replaceSymbolMap.put(originImportLine, newImportLine);
        return newImportLine;
    }

    // 将方法调用符号 -> 替换为 .
    public String methodInvoke2dotSeparate(String originMethodInvokeLine) {
        String newMethodInvokeLine = originMethodInvokeLine.replace("->", ".");
        replaceSymbolMap.put(originMethodInvokeLine, newMethodInvokeLine);
        return newMethodInvokeLine;
    }

    // 分析varType的类型，如果分析不出来就默认使用 Object
    public String thinkVarType(String varName) {
        return DEFAULT_OBJECT;
    }

    public String thinkVarType(String varName, String right) {
        if (StringUtil.isEmpty(right)) {
            return DEFAULT_OBJECT;
        }
        return DEFAULT_OBJECT;
    }

    // 通过左右边的表达式来分析 varType的类型，如果分析不出来就使用Object
    public String thinkVarType(String varName, String left, String right) {
        return null;
    }

    // 替换掉dollar符
    public String varReplaceDollar(String originVarName) {
        String newVarName = originVarName.replace("$", "");
        replaceSymbolMap.put(originVarName, newVarName);
        return newVarName;
    }

    // 将package的/线替换为 .
    public String packageReplaceSlashWithDot(String phpNamespace) {
        return phpNamespace.replace("\\", ".");
    }

    public String replaceKeywordNamespace(String phpNamespace) {
        return phpNamespace.replace("namespace", "");
    }

    // 将use后的/线替换为 .
    public String useReplaceSlashWithDot(String useNamespace) {
        return packageReplaceSlashWithDot(useNamespace);
    }

    // $this->tasks[]
    public String assignFieldNameReplaceArrayWithWhiteSpace(String fieldName) {
        if (fieldName.contains("[]")) {
            return fieldName.replace("[]", "");
        }
        return fieldName;
    }

    // $this->tasks[]
    public String replaceThisAndArrayWithWhiteSpace(String fieldName) {
        String newFieldName = fieldName;
        if (fieldName.startsWith("$this->")) {
            newFieldName = newFieldName.replace("$this->", "");
        }
        return assignFieldNameReplaceArrayWithWhiteSpace(newFieldName);
    }
}
